#ifndef _EDITOR_MAIN_H_
#define _EDITOR_MAIN_H_

#include "input/keyboard.h"
#include "input/mouse.h"
#include <string>
#include "num/named_set.h"

namespace editor
{

class	GameBase		// should inherit from this if it wants to drive the editor properly
{
public:
	virtual bool		Save(const std::string& Name) = 0;		// save to filename
	virtual bool		Load(const std::string& Name) = 0;		// load from filename
	virtual bool		Clear() = 0;		// clear everything in the game
};

class UISpriteSet;
class TextSelect;
class UISelection;
class EditorBrush;
class EditorMain
{
public:
						EditorMain(GameBase* pGame);
	virtual				~EditorMain();
	virtual void		Tick(float dt);
	virtual void		Render(const math::Vec2& Offset, float Scale);
	virtual void		KeyPressed(input::Keyboard::KEY* pKey);
	virtual void		KeyDown(input::Keyboard::KEY* pKey);
	virtual void		MouseMove(const math::Vec2& From, const math::Vec2& To);
	void				MouseButtonDown(input::Mouse::BUTTON_STATE* pKey, const math::Vec2& Pos);
	virtual	void		MouseButtonPressed(input::Mouse::BUTTON_STATE* pKey, const math::Vec2& Pos);
	virtual	void		MouseButtonReleased(input::Mouse::BUTTON_STATE* pKey, const math::Vec2& Pos) ;
	virtual void		MouseOnDrag(const math::Vec2& From, const math::Vec2& To) {};
	virtual void		MouseOnDrop(const math::Vec2& From, const math::Vec2& To) {};
	virtual void		MouseWheelMove(int WheelInfo, const math::Vec2& Pos);
	bool				ShowDebug();
	virtual void		Init();
	virtual void		Shutdown();
	void				SetBrush(EditorBrush*	pBrush);



	GameBase*			GetGame() { return m_pGame; }
	const math::Vec2&	GetMousePos() const { return m_MousePos; };
	void				SetHelp(const std::string& Text) { m_HelpText = Text; };
	bool				ShowHelp() const { return m_ShowHelp; };
	bool				ShouldSnapToGrid() const { return m_SnapToGrid; };

	// cached from the level
	float				GetScale() const { return m_Scale; };
	const math::Vec2&	GetOffset() const { return m_Offset; };

	// autosave system
	void				Autosave();
	void				Undo();
	void				Redo();

	// create UI Selection menus
	UISpriteSet*		CreateSpriteSelect(EditorBrush*	pBrush, const std::string& Name);
	TextSelect*			CreateTextSelect(EditorBrush*	pBrush, const std::string& Name);
	UISelection*		GetSelection() { return m_pSelectionSet; };


// brush generator
	typedef EditorBrush*	(*CreateBrushCB)(EditorMain* pMain);
	struct		CreateBrushData
	{
		std::string								Name;
		int										KeyID;
		CreateBrushCB							pCB;
	};

	EditorBrush*	CreateBrush(const std::string& Name);		// from name
	EditorBrush*	CreateBrush(int	KeyID);						// from keyboard shortcut
	void			AddBrush(const std::string& Name, int	KeyID, CreateBrushCB		pCB);

protected:
	virtual bool		CustomDelete(const math::Vec2& P) { return false; };
	virtual bool		CustomLMB(const math::Vec2& P) { return false; };

	EditorBrush*		m_pBrush;
	GameBase*			m_pGame;	// what's a better way of handling this?

	// grid
	math::Vec2					m_MousePos;
	bool						m_SnapToGrid;
	math::Vec2					m_GridOffset, m_GridSize;

	// help
	std::string					m_HelpText;
	bool						m_ShowHelp;
	bool						m_Auto;
	bool						m_RenderDebug;

	// UI for selecting stuff
	UISelection*				m_pSelectionSet;

	// cached from the level
	math::Vec2					m_Offset;
	float						m_Scale;

	num::NamedSet<CreateBrushData*>		m_BrushCreate;


public:
	static	int					m_AutoSaveIndex;
	static	int					m_AutoSaveHighest;

};

}//namespace editor

#endif //_EDITOR_MAIN_H_